﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Windows.Forms;

namespace ColorTools {
    public partial class ZoomControl : UserControl {
        [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
        public event EventHandler<ColorSelectedEventArgs> ColorSelected;

        private Bitmap _capture;

        public ZoomControl() {
            InitializeComponent();
        }

        private void DrawCapture(Graphics g) {
            float pixelSizeX = Width / (_capture.Width - 2);
            float pixelSizeY = Height / (_capture.Height - 2);
            Rectangle destRect = new Rectangle(-(int)(pixelSizeX / 2), -(int)(pixelSizeY / 2), (int)(Width + (pixelSizeX * 2)), (int)(Height + (pixelSizeY * 2)));

            ImageAttributes imgAttributes = new ImageAttributes();
            g.InterpolationMode = InterpolationMode.NearestNeighbor;
            g.DrawImage(_capture, destRect, 0, 0, _capture.Width, _capture.Height, GraphicsUnit.Pixel, imgAttributes);

            using (Pen blackPen = new Pen(Color.Black)) {
                for (float x = -1; x < Width; x += pixelSizeX) {
                    g.DrawLine(blackPen, x, 0, x, Height);
                }

                for (float y = -1; y < Height; y += pixelSizeY) {
                    g.DrawLine(blackPen, 0, y, Width, y);
                }

                int focusX = (int)(-1 + (pixelSizeX * Math.Floor((float)(_capture.Width - 2) / 2.0)));
                int focusY = (int)(-1 + (pixelSizeY * Math.Floor((float)(_capture.Height - 2) / 2.0)));
                Rectangle rect = new Rectangle(focusX, focusY, (int)pixelSizeX, (int)pixelSizeY);
                rect.Inflate(1, 1);
                g.DrawRectangle(blackPen, rect);
            }
        }

        private void ZoomControl_Paint(object sender, PaintEventArgs e) {
            if (_capture != null) {
                DrawCapture(e.Graphics);
            }
        }

        private void ProcessColorFinderClickInCaptureCoords(int captureX, int captureY) {
            Color pixel = _capture.GetPixel(captureX + 1, captureY + 1);
            ColorSelected(this, new ColorSelectedEventArgs(pixel));
        }

        private void ProcessColorFinderClick(int x, int y) {
            float pixelSizeX = Width / (_capture.Width - 2);
            float pixelSizeY = Height / (_capture.Height - 2);

            x = (int)(x / pixelSizeX);
            y = (int)(y / pixelSizeY);
            ProcessColorFinderClickInCaptureCoords(x, y);
        }

        private void _colorFinder_MouseMove(object sender, MouseEventArgs e) {
            if (e.Button == MouseButtons.Left) {
                ProcessColorFinderClick(e.X, e.Y);
            }
        }

        private void _colorFinder_MouseDown(object sender, MouseEventArgs e) {
            if (e.Button == MouseButtons.Left) {
                ProcessColorFinderClick(e.X, e.Y);
            }
        }

        public void SetImage(Bitmap image) {
            _capture = image;
            Refresh();
        }

        public Color GetColorAt(int x, int y) {
            return _capture.GetPixel(x + 1, y + 1);
        }
    }

    public class ColorSelectedEventArgs : EventArgs {
        private readonly Color _color;

        public ColorSelectedEventArgs(Color color) {
            _color = color;
        }

        public Color Color {
            get { return _color; }
        }
    }
}